package com.tjetc.controller;

import cn.hutool.core.bean.BeanUtil;
import com.tjetc.entity.po.Goods;
import com.tjetc.mapper.GoodsMapper;
import com.tjetc.service.IGoodsService;
import com.tjetc.utils.LockUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author gaoyongxiang
 * @version v1.0
 * @since 2025-10-20
 */
@RestController
@RequestMapping("/goods/")
@SuppressWarnings("all")
public class GoodsController {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private GoodsMapper goodsMapper;


    @Autowired
    private IGoodsService goodsService;



    /*
    @GetMapping("getById")
    public Goods getById(@RequestParam("id") Integer id) {
        // 实现缓存
        String key = "cache:goods:" + id;

        // 1. 从redis中获取
        Map<Object, Object> map = redisTemplate.opsForHash().entries(key);

        // 如果不为空，说明缓存中存在数据 直接返回即可
        if (!map.isEmpty()) {
            return BeanUtil.toBean(map, Goods.class);
        }
        // 2.从数据库中获取
        Goods goods = goodsMapper.selectById(id);
        if (Objects.isNull(goods)) {
            // 如果为null 说明数据根本不存在
            redisTemplate.opsForValue().set(key, "", Duration.ofMinutes(10L));
            return null;
        }
        // 3. 将查询的数据放入缓存中
        Map<String, Object> goodsMap = BeanUtil.beanToMap(goods);
        redisTemplate.opsForHash().putAll(key, goodsMap);
        return goods;
    }
    */

    // 使用锁解决缓存击穿问题
    @GetMapping("getById")
    public Goods getById(@RequestParam("id") Integer id) {
        // 实现缓存
        String key = "cache:goods:" + id;

        // 1. 从redis中获取
        Map<Object, Object> map = redisTemplate.opsForHash().entries(key);

        // 如果不为空，说明缓存中存在数据 直接返回即可
        if (!map.isEmpty()) {
            return BeanUtil.toBean(map, Goods.class);
        }

        // 设置互斥锁
        String lockKey = "lock:get:" + id;
        Goods goods = new Goods();
        try {
            boolean isLock = LockUtil.tryLock(lockKey);
            // 没有获取锁
            if (!isLock) {
                return null;
            }
            // 2.从数据库中获取
            goods = goodsMapper.selectById(id);
            if (Objects.isNull(goods)) {
                // 如果为null 说明数据根本不存在
                redisTemplate.opsForValue().set(key, "", Duration.ofMinutes(10L));
                return null;
            }
            // 3. 将查询的数据放入缓存中
            Map<String, Object> goodsMap = BeanUtil.beanToMap(goods);
            redisTemplate.opsForHash().putAll(key, goodsMap);
        } catch (Exception e) {

        } finally {
            LockUtil.unLock(lockKey);

        }
        return goods;
    }

    // 更新数据库
    @PostMapping("updateById")
    public String updateById(@RequestBody Goods goods) {
        return goodsService.updateById(goods);
    }
}
